﻿namespace MonitorLock
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            MonitorTryLock();

            Console.ReadLine();
        }


        /// <summary>
        /// lock锁测试
        /// </summary>
        static void lockTest()
        {
            object lockObj = new object();

            int count = 10;
            while (count-- > 0)
            {
                Task.Run(() =>
                {
                    lock (lockObj)
                    {
                        Console.WriteLine($"{Environment.CurrentManagedThreadId}:{count}");
                        Task.Delay(5000).Wait();
                    }
                });
            }
        }


        static void MonitorTest()
        {
            object lockObj = new object();
            int count = 10;
            while (count-- > 0)
            {
                Task.Run(() =>
                {
                    bool token = false;
                    try
                    {
                        Monitor.Enter(lockObj, ref token);
                        throw new Exception("测试锁");
                    }
                    finally
                    {
                        if (token) Monitor.Exit(lockObj);
                    }
                });
            }
        }


        static void MonitorTryLock()
        {
            object lockObj = new object();
            int count = 100;
            while (count-->0)
            {
                Task.Run(async () =>
                {
                    if (Monitor.TryEnter(lockObj, 1000))
                    {
                        try
                        {
                            Console.WriteLine($"开始：{DateTime.Now}");
                            await Task.Delay(500);
                            Console.WriteLine($"结束：{DateTime.Now}");
                        }
                        finally
                        {
                            Monitor.Exit(lockObj);
                        }
                    }
                    else
                    {
                        Console.WriteLine($"获取锁失败：{DateTime.Now}");
                    }
                });
            }

        }
    }
}
